home *** CD-ROM | disk | FTP | other *** search
- /*
- * getattr This module handles the NFS attributes.
- *
- * Authors: Mark A. Shand, May 1988
- * Donald J. Becker, <becker@super.org>
- * Rick Sladkey, <jrs@world.std.com>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Olaf Kirch, <okir@monad.swb.de>
- *
- * Copyright 1988 Mark A. Shand
- * This software maybe be used for any purpose provided
- * the above copyright notice is retained. It is supplied
- * as is, with no warranty expressed or implied.
- */
-
- #include "nfsd.h"
-
- /*
- * Set file attributes based on file handle
- */
- nfsstat fh_setattr(fh, attr, s, rqstp, flags)
- nfs_fh *fh;
- sattr *attr;
- struct stat *s;
- struct svc_req *rqstp;
- int flags;
- {
- char *path;
- nfsstat status;
-
- if ((path = fh_path(fh, &status)) == NULL) {
- dprintf(D_CALL, "setattr failed: No such file.\n");
- return (NFSERR_STALE);
- }
- return setattr(path, attr, s, rqstp, flags);
- }
-
- /*
- * Set file attributes given the path. The flags argument
- * determines if we have to stat the file or if the stat buf
- * passed in s contains valid data.
- * As we go along and modify the file attributes, we update the
- * fields of this stat structure.
- */
- nfsstat setattr(path, attr, s, rqstp, flags)
- char *path;
- sattr *attr;
- struct stat *s;
- struct svc_req *rqstp;
- int flags;
- {
- struct stat sbuf;
-
- if (s == NULL) {
- s = &sbuf;
- flags |= SATTR_STAT;
- }
-
- if ((flags & SATTR_STAT) && lstat(path, (s = &sbuf)) < 0) {
- dprintf(D_CALL, "setattr: couldn't stat %s! errno=%d\n",
- path, errno);
- return nfs_errno();
- }
-
- if (flags & SATTR_SIZE) {
- unsigned int size = attr->size;
-
- if (S_ISREG(s->st_mode) && size != -1) {
- if (truncate(path, size) < 0)
- goto failure;
- s->st_size = size;
- }
- }
-
- if (flags & SATTR_UTIMES) {
- unsigned int a_secs = attr->atime.seconds;
- unsigned int m_secs = attr->mtime.seconds;
-
- if ((a_secs != -1 && a_secs != s->st_atime)
- || (m_secs != -1 && m_secs != s->st_mtime)) {
- struct timeval tvp[2];
- tvp[0].tv_sec = attr->atime.seconds;
- tvp[0].tv_usec = attr->atime.useconds;
- tvp[1].tv_sec = attr->mtime.seconds;
- tvp[1].tv_usec = attr->mtime.useconds;
- if (utimes(path, tvp) < 0)
- goto failure;
- if (attr->mtime.seconds != -1)
- s->st_atime = attr->atime.seconds;
- if (attr->mtime.seconds != -1)
- s->st_mtime = attr->mtime.seconds;
- }
- }
-
- if (flags & SATTR_CHMOD) {
- unsigned int mode = attr->mode;
-
- if (mode != -1 && (mode & 07777) != (s->st_mode & 07777)) {
- if (chmod(path, mode) < 0)
- goto failure;
- s->st_mode = (s->st_mode & ~07777) | (mode & 07777);
- }
- }
-
- if (flags & SATTR_CHOWN) {
- uid_t uid = attr->uid;
- gid_t gid = attr->gid;
-
- if (uid != (uid_t)-1)
- uid = luid(uid, nfsmount, rqstp);
- if (gid != (gid_t)-1)
- gid = lgid(gid, nfsmount, rqstp);
-
- if ((uid != (uid_t)-1 && uid != s->st_uid)
- || (gid != (gid_t)-1 && gid != s->st_gid)) {
- if (lchown(path, uid, gid) < 0)
- goto failure;
- if (uid != (uid_t)-1) s->st_uid = uid;
- if (gid != (gid_t)-1) s->st_gid = gid;
- }
- }
-
- return (NFS_OK);
-
- failure:
- return nfs_errno();
- }
-